package com.gopay.common.user.dao.impl;

import com.gopay.common.base.dao.impl.BaseDAOImpl;
import com.gopay.common.cipher.utils.SensitiveInfoUtils;
import com.gopay.common.constants.trans.CustCategory;
import com.gopay.common.constants.trans.CustChannelNum;
import com.gopay.common.constants.trans.PayChannel;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.user.identify.PersIdUsedQuota;
import com.gopay.common.domain.user.identify.RcAcctPayLimit;
import com.gopay.common.domain.user.identify.RcPayVerifyLimit;
import com.gopay.common.user.dao.PersCertChannelDtlDao;
import com.gopay.common.user.dao.PersonIdentifyDAO;
import com.gopay.common.user.dao.RcPayVerifyLimitDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.NumberUtils;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



/**
 * 身份证已用额度DAO实现类
 *
 * @RoleInfoDAOImpl.java
 * @author songfengli
 * @2013-8-8 下午04:19:12 www.gopay.com.cn Inc.All rights reserved.
 */

@Repository("personIdentifyDAO")
public class PersonIdentifyDAOImpl extends BaseDAOImpl<PersIdUsedQuota, Serializable> implements PersonIdentifyDAO{

	@Resource(name = "persCertChannelDtlDao")
    private PersCertChannelDtlDao persCertChannelDtlDao;

    @Resource(name = "rcPayVerifyLimitDao")
    private RcPayVerifyLimitDAO rcPayVerifyLimitDao;

    @Override
    public PersIdUsedQuota getIdentityInfo(String certNo){
        String hql = "from PersIdUsedQuota t where t.identifyNo in (:certNo)";
        Map<String, Object> paramMap = new HashMap<>();
        // pci dak.wang 20170606
        certNo = SensitiveInfoUtils.smartDecryptWithCheck(certNo);
        paramMap.put("certNo", SensitiveInfoUtils.getAllHisCipherArray(certNo));
        List<PersIdUsedQuota> PersIdUsedQuotaList= this.findByHql(hql, paramMap);
        if (PersIdUsedQuotaList == null || PersIdUsedQuotaList.size() == 0) {
            return null;
        }
        return PersIdUsedQuotaList.get(0);
    }

//此方法不满足主订单单日交易额度，因钱包的发红包交易特殊，使用新方法，此原方法注释掉做备份 modify by tangyang at 20161222
    //主订单单日交易额度
//    @SuppressWarnings("rawtypes")
//    public BigDecimal findMainorderAmt(String custId){
//       String totalOrderAmtSql="select sum(t.mer_txn_amt) as mer_txn_amt "
//       		+ "from cps_gen_main_order t "
//       		+ "where t.txn_sta_cd=:txn_sta_cd  "
//       		+ "and t.gopay_int_txn_cd !=:gopay_int_txn_cd  and t.pay_channel=:pay_channel and t.pay_cust_id=:custId and to_char(t.mer_txn_tm,'yyyy-MM-dd')=:date";
//        BigDecimal totayOrderAmt= new BigDecimal("0");//单日交易累计金额
//
//        Map<String, Object> totalOrderMap = new HashMap<String, Object>();
//        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
//        Date date=new Date();
//        String dateTime=sdf.format(date);
//        totalOrderMap.put("date", dateTime);
//        totalOrderMap.put("custId", custId);
//        totalOrderMap.put("pay_channel", PayChannel._02.value);
//        totalOrderMap.put("gopay_int_txn_cd", IntTxnCd._00800.value);
//        totalOrderMap.put("txn_sta_cd", TxnStaCode.TXN_STA_CD_20000.value);
//
//
//        List totalOrderAmtList=this.findBySql(totalOrderAmtSql, totalOrderMap);//查询出当日已完成的订单金额
//        if(null!=(totalOrderAmtList.get(0))){
//            totayOrderAmt=(BigDecimal) totalOrderAmtList.get(0);
//        }
//         return totayOrderAmt;
//    }

  /** 余额出款：状态为20000的订单不统计00800、01609和状态为30402的订单统计10608
   *  减去 状态为20000的订单01610且原10608的pay_channel=02
   * modify by tangyang at 20161222
   */
  //查询主订单单日交易额度
    @Override
    @SuppressWarnings("rawtypes")
    public BigDecimal findMainorderAmt(String custId){
       String totalOrderAmtSql="select sum(mer_txn_amt)"
    		   + "  from (select sum(t.mer_txn_amt) as mer_txn_amt"
    		   + "          from cps_gen_main_order t"
    		   + "         where t.pay_cust_id = :pay_cust_id1"
    		   + "           and t.txn_sta_cd = :txn_sta_cd1"
    		   + "           and t.pay_channel = :pay_channel1"
    		   + "           and t.gopay_int_txn_cd != :gopay_int_txn_cd11"
    		   + "           and t.gopay_int_txn_cd != :gopay_int_txn_cd12"
    		   + "           and t.mer_txn_tm >= to_date(:mer_txn_tm1,'yyyy-MM-dd')"
    		   + "        union all"
    		   + "        select sum(t.mer_txn_amt) as mer_txn_amt"
    		   + "          from cps_gen_main_order t"
    		   + "         where t.pay_cust_id = :pay_cust_id2"
    		   + "           and t.txn_sta_cd = :txn_sta_cd2"
    		   + "           and t.pay_channel = :pay_channel2"
    		   + "           and t.gopay_int_txn_cd = :gopay_int_txn_cd2"
    		   + "           and t.mer_txn_tm >= to_date(:mer_txn_tm2,'yyyy-MM-dd')"
    		   + "        union all"
    		   + "        select -sum(m.mer_txn_amt) as mer_txn_amt"
    		   + "          from cps_gen_main_order m"
    		   + "          left join cps_gen_main_order r"
    		   + "            on r.gopay_order_id = m.relevance_gopay_order_id"
    		   + "         where m.main_recv_cust_id = :main_recv_cust_id3"
    		   + "           and m.gopay_int_txn_cd = :gopay_int_txn_cd31"
    		   + "           and m.txn_sta_cd = :txn_sta_cd31"
    		   + "           and m.mer_txn_tm >= to_date(:mer_txn_tm3,'yyyy-MM-dd')"
    		   + "           and r.txn_sta_cd = :txn_sta_cd32"
    		   + "           and r.pay_channel = :pay_channel3"
    		   + "           and r.gopay_int_txn_cd = :gopay_int_txn_cd32)";
        BigDecimal totayOrderAmt= new BigDecimal("0");//单日交易累计金额

        Map<String, Object> totalOrderMap = new HashMap<>();

        String dateTime= DateUtils.format(new Date(),"yyyy-MM-dd");

        totalOrderMap.put("pay_cust_id1", custId);
        totalOrderMap.put("txn_sta_cd1", TxnStaCode.TXN_STA_CD_20000.value);
        totalOrderMap.put("pay_channel1", PayChannel._02.value);
        totalOrderMap.put("gopay_int_txn_cd11", IntTxnCd._00800.value);
        totalOrderMap.put("gopay_int_txn_cd12", IntTxnCd._01609.value);
        totalOrderMap.put("mer_txn_tm1", dateTime);
        
        totalOrderMap.put("pay_cust_id2", custId);
        totalOrderMap.put("txn_sta_cd2", TxnStaCode.TXN_STA_CD_30402.value);
        totalOrderMap.put("pay_channel2", PayChannel._02.value);
        totalOrderMap.put("gopay_int_txn_cd2", IntTxnCd._01608.value);
        totalOrderMap.put("mer_txn_tm2", dateTime);
        
        totalOrderMap.put("main_recv_cust_id3", custId);
        totalOrderMap.put("gopay_int_txn_cd31", IntTxnCd._01610.value);
        totalOrderMap.put("txn_sta_cd31", TxnStaCode.TXN_STA_CD_20000.value);
        totalOrderMap.put("mer_txn_tm3", dateTime);
        totalOrderMap.put("txn_sta_cd32", TxnStaCode.TXN_STA_CD_20000.value);
        totalOrderMap.put("pay_channel3", PayChannel._02.value);
        totalOrderMap.put("gopay_int_txn_cd32", IntTxnCd._01608.value);
        
        List totalOrderAmtList=this.findBySql(totalOrderAmtSql, totalOrderMap);//查询出当日已完成的订单金额
        if(null!=(totalOrderAmtList.get(0))){
            totayOrderAmt=(BigDecimal) totalOrderAmtList.get(0);
        }
         return totayOrderAmt;
    }
   
   
   
    @Override
    public void updateIndentify(PersIdUsedQuota persIdUsedQuota){
        String updateSql = "update pers_id_used_quota_sec t set t.all_used_quota=:all_used_quota,t.year_used_quota=:year_used_quota,t.last_upd_user_id=:userId,t.last_upd_ts=:date where t.identify_no in(:certNo)";
        
        Map<String, Object> tmap = new HashMap<>();
        tmap.put("all_used_quota", persIdUsedQuota.getAllUsedQuota());
        tmap.put("year_used_quota", persIdUsedQuota.getYearUsedQuota());
        tmap.put("userId", persIdUsedQuota.getLastUpdUserId());
        tmap.put("date", new Date());
        // pci dak.wang 20170606
        String certNo = SensitiveInfoUtils.smartDecryptWithCheck(persIdUsedQuota.getIdentifyNo());
        tmap.put("certNo", SensitiveInfoUtils.getAllHisCipherArray(certNo));
        this.updateBySql(updateSql,tmap);
    }
    

    @Override
    public Map<String, Object> getAcctQuotaByCertNo(String custId,String certNo) {
        BigDecimal allUsedQuota = new BigDecimal("0.00");//账户限制额度
        BigDecimal yearUsedQuota= new BigDecimal("0.00");//年累计额度
        Double avaAmt = 0.00;
        String quotaHql = "from PersIdUsedQuota  where identifyNo in (:identifyNo)";
        Map<String, Object> quotaParam = new HashMap<>();
        // pci dak.wang 20170606
        certNo = SensitiveInfoUtils.smartDecryptWithCheck(certNo);
        quotaParam.put("identifyNo", SensitiveInfoUtils.getAllHisCipherArray(certNo));
        List<PersIdUsedQuota> quotaList =  this.findByHql(quotaHql, quotaParam);
        
        //年度额度
        Map<String, Object> retData = new HashMap<>();
        //账户类别
        String acctType = CustChannelNum.custType(persCertChannelDtlDao.findSuccessCertChannelCountsByCustId(custId));
        if( quotaList != null && quotaList.size() > 0 ){
            PersIdUsedQuota quota = quotaList.get(0);
            if( CustCategory.one.value.equals(acctType) ){
                yearUsedQuota = quota.getAllUsedQuota();
            }else{
                yearUsedQuota = quota.getYearUsedQuota();
            }
        }
        //账户限制额度
        String limitHql = "from RcAcctPayLimit  where acctType=:acctType ";
        Map<String, Object> limitParam = new HashMap<>();
        limitParam.put("acctType", acctType);
        List limitList = this.findByHql(limitHql, limitParam);
        if( limitList != null && limitList.size() > 0 ){
            RcAcctPayLimit payLimit = (RcAcctPayLimit) limitList.get(0);
            allUsedQuota = payLimit.getAcctLimit();
        }
        //可用额度
        if( allUsedQuota.compareTo(yearUsedQuota) == 1 ){
            avaAmt = allUsedQuota.subtract(yearUsedQuota).doubleValue();
        }
        retData.put("allUsedQuota", allUsedQuota);//账户限制额度
        retData.put("yearUsedQuota", yearUsedQuota);//账户已用额度
        retData.put("avaAmt", avaAmt);//账户剩余额度
        retData.put("acctType", acctType);//账户类别
        return retData;
    }
    
    @Override
    public PersIdUsedQuota findByIndentifyNo(String certNo) {
        String quotaHql = "from PersIdUsedQuota  where identifyNo in (:identifyNo)";
        Map<String, Object> quotaParam = new HashMap<>();
        // pci dak.wang 20170606
        certNo = SensitiveInfoUtils.smartDecryptWithCheck(certNo);
        quotaParam.put("identifyNo", SensitiveInfoUtils.getAllHisCipherArray(certNo));
        List<PersIdUsedQuota> list =  this.findByHql(quotaHql, quotaParam);
        
        if(list == null || list.size() == 0){
            return null;
        }else{
            return list.get(0);
        }
    }

	@Override
	public BigDecimal findAvailableQuotaByPayAuthType(String payAutType, String custId) {
		BigDecimal availableQuota = new BigDecimal("0.00");
		RcPayVerifyLimit rcPayVerifyLimit = rcPayVerifyLimitDao.findByCode(payAutType);
		BigDecimal totalOrderAmt = findMainorderAmt(custId);
		if( totalOrderAmt.compareTo(rcPayVerifyLimit.getTodayTotalLimit()) > 0 ){
			return availableQuota;
		}
		availableQuota = rcPayVerifyLimit.getTodayTotalLimit().subtract(totalOrderAmt);
		return new BigDecimal(NumberUtils.format2PointWithHalfUp(availableQuota));
	}
    
    
    
}
